{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 1.类的结构"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 1.1 术语--实例"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 1 创建出来的 对象 叫做 类 的 实例\n",
    "# 2 创建对象的 动作 叫做 实例化\n",
    "# 3 对象的属性 叫做 实例属性\n",
    "# 4 对象调用的方法 叫做 实例方法\n",
    "\n",
    "# • 每一个对象 都有自己 独立的内存空间，保存各自不同的属性\n",
    "# • 多个对象的方法，在内存中只有一份，在调用方法时，需要把对象的引用 传递到方法内部（知道为啥要搞 self 了吧"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 1.2 类是一个特殊的对象"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 一切皆对象\n",
    "# • class AAA: 定义的类属于 类对象\n",
    "# • obj1 = AAA() 属于 实例对象\n",
    "# • 在程序运行时，类 同样 会被加载到内存\n",
    "# • 在 Python 中，类 是一个特殊的对象 —— 类对象\n",
    "# • 在程序运行时，类对象 在内存中 只有一份，使用 一个类 可以创建出 很多个对象实例\n",
    "# • 除了封装 实例 的 属性 和 方法外，类对象 还可以拥有自己的 属性 和 方法\n",
    "# d) 类属性\n",
    "# e) 类方法\n",
    "# • 通过 类名. 的方式可以 访问类的属性 或者 调用类的方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 2.类属性和实例属性"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 2.1 概念和使用"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "现在创建了 3 个工具\n",
      "3\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "class Tool(object):\n",
    "# 使用赋值语句，定义类属性，记录创建工具对象的总数\n",
    "# 类属性是指定义在类的内部而且在方法的外部的属性\n",
    "    count = 0\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "        # 针对类属性做一个计数+1\n",
    "        Tool.count += 1\n",
    "# 创建工具对象\n",
    "tool1 = Tool(\"斧头\")\n",
    "tool2 = Tool(\"榔头\")\n",
    "tool3 = Tool(\"铁锹\")\n",
    "# 知道使用 Tool 类到底创建了多少个对象?\n",
    "print(\"现在创建了 %d 个工具\" % Tool.count)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 2.2 属性的获取机制"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 在 Python 中 属性的获取 存在一个 向上查找机制\n",
    "# 首先在对象内部查找对象属性\n",
    "# 没有找到就会向上查找类属性\n",
    "\n",
    "print(Tool.count)\n",
    "print(tool1.count) #不建议"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 3.类方法和静态方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 3.1 类方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# • 类属性 就是针对 类对象 定义的属性\n",
    "# – 使用 赋值语句 在 class 关键字下方可以定义 类属性\n",
    "# – 类属性 用于记录 与这个类相关 的特征\n",
    "# • 类方法 就是针对 类对象 定义的方法\n",
    "# – 在 类方法 内部可以直接访问 类属性 或者调用其他的 类方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 语法如下\n",
    "# @classmethod\n",
    "# def 类方法名(cls):\n",
    "#      pass\n",
    "# • 类方法需要用 修饰器 @classmethod 来标识，告诉解释器这是一个类方法\n",
    "# • 类方法的 第一个参数 应该是 cls\n",
    "# – 由 哪一个类 调用的方法，方法内的 cls 就是 哪一个类的引用\n",
    "# – 这个参数和 实例方法 的第一个参数是 self 类似\n",
    "# – 提示 使用其他名称也可以，不过习惯使用 cls\n",
    "# • 通过 类名. 调用 类方法，调用方法时，不需要传递 cls 参数\n",
    "# • 在方法内部\n",
    "# – 可以通过 cls. 访问类的属性\n",
    "# – 也可以通过 cls. 调用其他的类方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "现在创建了3个工具\n",
      "工具对象的总数3\n",
      "工具对象的总数3\n",
      "现在创建了3个工具\n"
     ]
    }
   ],
   "source": [
    "class Tool:\n",
    "    count = 0\n",
    "\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "\n",
    "        Tool.count += 1\n",
    "\n",
    "    @classmethod\n",
    "    def show_tool_count(cls):\n",
    "        print(\"工具对象的总数{}\".format(cls.count))\n",
    "\n",
    "\n",
    "tool1 = Tool(\"斧头\")\n",
    "tool2 = Tool(\"榔头\")\n",
    "tool3 = Tool(\"铁锹\")\n",
    "print(\"现在创建了{}个工具\".format(Tool.count))\n",
    "tool1.show_tool_count()\n",
    "Tool.show_tool_count()\n",
    "print(\"现在创建了{}个工具\".format(tool1.count))  # 不推荐"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 3.2 静态方法"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 干一件事情不想传参，很简单，归成一类可以用静态方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "小狗要跑...\n"
     ]
    }
   ],
   "source": [
    "class Dog(object):\n",
    "    @staticmethod\n",
    "    def run():\n",
    "        # 不访问实例属性/类属性\n",
    "        print(\"小狗要跑...\")\n",
    "        # 通过类名.调用静态方法 - 不需要创建对象\n",
    "Dog.run()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 需求\n",
    "# 1 设计一个 Game 类\n",
    "# 2 属性：\n",
    "# – 定义一个 类属性 top_score 记录游戏的 历史最高分\n",
    "# – 定义一个 实例属性 player_name 记录 当前游戏的玩家姓名\n",
    "# 3 方法：\n",
    "# – 静态方法 show_help 显示游戏帮助信息\n",
    "# – 类方法 show_top_score 显示历史最高分\n",
    "# – 实例方法 start_game 开始当前玩家的游戏\n",
    "# 4 主程序步骤\n",
    "# – 1) 查看帮助信息\n",
    "# – 2) 查看历史最高分\n",
    "# – 3) 创建游戏对象，开始游戏"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "帮助信息\n",
      "历史最高分：0\n",
      "开始游戏\n"
     ]
    }
   ],
   "source": [
    "class Game:\n",
    "    top_score = 0\n",
    "\n",
    "    def __init__(self,player_name):\n",
    "        self.player_name = player_name\n",
    "\n",
    "    @staticmethod\n",
    "    def show_help():\n",
    "        print(\"帮助信息\")\n",
    "\n",
    "    @classmethod\n",
    "    def show_top_socre(cls):\n",
    "        print(\"历史最高分：{}\".format(cls.top_score))\n",
    "\n",
    "    def start_game(self):\n",
    "        print(\"开始游戏\")\n",
    "\n",
    "Game.show_help()\n",
    "Game.show_top_socre()\n",
    "xiaoming = Game(\"小明\")\n",
    "xiaoming.start_game()\n",
    "\n",
    "# 案例小结\n",
    "# 1 实例方法 —— 方法内部需要访问 实例属性\n",
    "# – 实例方法 内部可以使用 类名. 访问类属性\n",
    "# 2 类方法 —— 方法内部 只 需要访问 类属性\n",
    "# 3 静态方法 —— 方法内部，不需要访问 实例属性 和 类属性\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}